package com.imooc.activitiweb.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import com.imooc.activitiweb.mapper.FormConfigDefMapper;
import com.imooc.activitiweb.mapper.FormControlDefMapper;
import com.imooc.activitiweb.pojo.FormConfigDef;
import com.imooc.activitiweb.pojo.FormControlDef;

import com.imooc.activitiweb.util.AjaxResponse;
import com.imooc.activitiweb.util.GlobalConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;


import java.util.*;


@RestController
@RequestMapping("/formDef")
public class FormDefController {



    @Autowired
    private FormControlDefMapper formControlDefMapper;

    @Autowired
    private FormConfigDefMapper formConfigDefMapper;


    //存入表单配置基本数据
    @PostMapping ("/add")
    public AjaxResponse add(@RequestBody String data){
        try{
            //得到前端传过来的json数据
            JSONObject jsonObject = JSON.parseObject(data);
            //分别获取一级json数据中的taskID和form
            String taskID = jsonObject.get("taskID").toString();
            if(StringUtils.isEmpty(taskID)){
                return  AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(),"taskID任务编号不能为空",null);
            }
            //先删除控件定义表和控件配置表中此taskId对应的原有控件
            formControlDefMapper.deleteFormControlDefByTaskID(taskID);
            formConfigDefMapper.deleteFormConfigDefByTaskID(taskID);
            //获取前端传来的json数据中的表单form
            JSONObject form = (JSONObject) jsonObject.get("form");
            //分别获取form数据中的formConfig和widgetList
            JSONObject formConfig = (JSONObject) form.get("formConfig");
            JSONArray widgetList = (JSONArray) form.get("widgetList");

            //创建一个集合来保存递归表单数据解析到的控件信息
            List<JSONObject> controlInformationList=new LinkedList<>();
            //调用递归方法解析json数据 拿到json表单数据中的每个控件的信息 此时每个控件的信息已经存入controlInformationList中
            controlInformationList = getControlInformation(form,controlInformationList);

            for (int i = 0; i < controlInformationList.size(); i++) {
                //集合controlInformationList已存入当前表单中的控件信息
                JSONObject controlInformation = controlInformationList.get(i);
                //获取控件信息中的几个属性字段
                Object controlId = controlInformation.get("id");
                Object controlType = controlInformation.get("type");
                JSONObject options = (JSONObject) controlInformation.get("options");
                Object defaultValue = options.get("defaultValue");
                Object isParams = options.get("isParams");
                //创建一个FormControlDef对象为其属性赋值
                FormControlDef formControlDef=new FormControlDef();
                formControlDef.setTaskid(taskID);
                formControlDef.setControlid(controlId==null?"":controlId.toString());
                formControlDef.setControltype(controlType==null?"":controlType.toString());
                formControlDef.setDefaultvalue(defaultValue==null?"":defaultValue.toString());
                formControlDef.setControlvalue(controlInformation.toString());

                if(isParams==null){
                    formControlDef.setIsparams(false);
                }else{
                    formControlDef.setIsparams((boolean)isParams);
                }
                formControlDefMapper.insert(formControlDef);//插入表单控件定义表
            }
            //创建一个FormConfigDef对象为其属性赋值
            FormConfigDef formConfigDef=new FormConfigDef();
            formConfigDef.setTaskid(taskID);
            formConfigDef.setFormconfig(formConfig==null?"":formConfig.toString());
            formConfigDef.setWidgetlist(widgetList.toString());
            //todo::添加的所有数据，如果不创建实际的工作流，都会冗余数据，需要在删除工作流的时候，查一下没有对应上的任务，都删了
            formConfigDefMapper.insert(formConfigDef);//插入表单控件配置表

            return  AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),"表单定义保存成功",null);
        }catch (Exception e){
            return  AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(),"表单定义保存失败",e.toString());
        }
    }

    //点击表单定义返回表单配置数据来渲染
    @PostMapping("/show")
    public AjaxResponse show(String taskID){
        try{
            //通过taskID查询表单控件配置表
            FormConfigDef formConfigDefs = formConfigDefMapper.selectFormConfigDefByTaskID(taskID);

            //判断是否为空 如果是 就说明当前taskId并未创建 并返回
            if(formConfigDefs==null){
                return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),"","");
            }
            String widgetList = formConfigDefs.getWidgetlist();//得到一级json中的widgetList信息
            JSONArray jsonWidgetList = JSONArray.parseArray(widgetList);//将widgetList转为json格式
            String formConfig = formConfigDefs.getFormconfig();//得到配置信息formConfig
            JSONObject jsonFormConfig = JSONObject.parseObject(formConfig);//将formConfig转为json格式
            //将json数据和formConfig结合并返回给前端进行渲染
            JSONObject jsonForm=new JSONObject();
            jsonForm.put("widgetList",jsonWidgetList);
            jsonForm.put("formConfig",jsonFormConfig);
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),"获取信息成功",jsonForm);
        }catch (Exception e){
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(),"获取信息失败",e.toString());
        }
    }


    /**
     * 递归遍历解析JSON数据 拿到需要的控件
     * @param objJson
     */
    public  List<JSONObject>  getControlInformation(Object objJson,List<JSONObject> controlInformationList){
        //如果obj为json数组
        if(objJson instanceof JSONArray){
            JSONArray objArray = (JSONArray)objJson;
            for (int i = 0; i < objArray.size(); i++) {
                getControlInformation(objArray.get(i),controlInformationList);
            }
        }
        //如果为json对象
        else if(objJson instanceof JSONObject){
            JSONObject controlInformation = (JSONObject)objJson;
            Iterator it = controlInformation.keySet().iterator();
            while(it.hasNext()){
                String key = it.next().toString();
                Object value = controlInformation.get(key);
                //如果得到的是数组
                if(value instanceof JSONArray){
                    JSONArray objArray = (JSONArray)value;
                    getControlInformation(objArray,controlInformationList);
                }
                //如果key中是一个json对象
                else if(value instanceof JSONObject){
                    getControlInformation((JSONObject)value,controlInformationList);
                }
                //如果key中是其他
                else{
                    if(key.equals("formItemFlag")){
                        //用list来接收需要的控件
                        controlInformationList.add(controlInformation);
                    }
                }
            }
        }
        return controlInformationList;
    }

}
